package org.proteored.miapeapi.xml.pride.adapter;

import org.apache.log4j.Logger;
import org.proteored.miapeapi.cv.ControlVocabularyManager;
import org.proteored.miapeapi.exceptions.IllegalMiapeArgumentException;
import org.proteored.miapeapi.experiment.model.Experiment;
import org.proteored.miapeapi.experiment.model.ExperimentList;
import org.proteored.miapeapi.experiment.model.Replicate;
import org.proteored.miapeapi.interfaces.Adapter;
import org.proteored.miapeapi.interfaces.ms.MiapeMSDocument;
import org.proteored.miapeapi.interfaces.msi.MiapeMSIDocument;
import org.proteored.miapeapi.xml.pride.autogenerated.ExperimentCollection;
import org.proteored.miapeapi.xml.pride.autogenerated.ExperimentType;
import org.proteored.miapeapi.xml.pride.autogenerated.GelFreeIdentificationType;
import org.proteored.miapeapi.xml.pride.autogenerated.ObjectFactory;
import org.proteored.miapeapi.xml.pride.util.PrideControlVocabularyXmlFactory;

public class ExperimentCollectionAdapterFromExperiment implements
		Adapter<ExperimentCollection> {
	private static Logger log = Logger.getLogger("log4j.logger.org.proteored");

	private final ObjectFactory factory;
	private final ControlVocabularyManager cvManager;

	private final Experiment experiment;

	private final boolean addPeakList;
	private final boolean gelBasedExperiment;
	private final boolean removeNoMatchedSpectra;

	private final boolean excludeNonConclusiveProteinGroups;
	private final String prideGenerationSoftware;

	/**
	 * Creates a PRIDE XML from several MIAPE MSs and MIAPE MSIs (
	 * {@link MiapeMSDocument} and {@link MiapeMSIDocument}) that comes from a
	 * {@link ExperimentList}.<br>
	 * For each {@link Experiment} a {@link ExperimentType} will be created in
	 * the PRIDE XML file.<br>
	 * Proteins from all {@link Replicate} will be added to the same list of
	 * {@link GelFreeIdentificationType}.<br>
	 * By default, all spectra will be included (matched and not matched
	 * spectra).
	 * 
	 * @param experiment
	 * @param controlVocabularyUtil
	 * @param addPeakList
	 */
	public ExperimentCollectionAdapterFromExperiment(Experiment experiment,
			ControlVocabularyManager controlVocabularyUtil,
			boolean addPeakList, boolean excludeNonConclusiveProteinGroups) {

		this(experiment, false, controlVocabularyUtil, addPeakList,
				excludeNonConclusiveProteinGroups);
	}

	public ExperimentCollectionAdapterFromExperiment(Experiment experiment,
			ControlVocabularyManager controlVocabularyUtil,
			boolean addPeakList, boolean excludeNonConclusiveProteinGroups,
			String prideGenerationSoftware) {

		this(experiment, false, controlVocabularyUtil, addPeakList,
				excludeNonConclusiveProteinGroups, prideGenerationSoftware);
	}

	public ExperimentCollectionAdapterFromExperiment(Experiment experiment,
			boolean gelbasedExperiment,
			ControlVocabularyManager controlVocabularyUtil,
			boolean addPeakList, boolean excludeNonConclusiveProteinGroups) {
		if (experiment == null) {
			throw new IllegalMiapeArgumentException(
					"Error creating PRIDE XML from null ExperimentList!");
		}
		this.factory = new ObjectFactory();
		this.cvManager = controlVocabularyUtil;
		this.experiment = experiment;
		this.addPeakList = addPeakList;
		this.removeNoMatchedSpectra = false;
		this.gelBasedExperiment = gelbasedExperiment;
		this.excludeNonConclusiveProteinGroups = excludeNonConclusiveProteinGroups;
		this.prideGenerationSoftware = "ProteoRed MIAPE Extractor";
	}

	public ExperimentCollectionAdapterFromExperiment(Experiment experiment,
			boolean gelbasedExperiment,
			ControlVocabularyManager controlVocabularyUtil,
			boolean addPeakList, boolean excludeNonConclusiveProteinGroups,
			String prideGenerationSoftware) {
		if (experiment == null) {
			throw new IllegalMiapeArgumentException(
					"Error creating PRIDE XML from null ExperimentList!");
		}
		this.factory = new ObjectFactory();
		this.cvManager = controlVocabularyUtil;
		this.experiment = experiment;
		this.addPeakList = addPeakList;
		this.removeNoMatchedSpectra = false;
		this.gelBasedExperiment = gelbasedExperiment;
		this.excludeNonConclusiveProteinGroups = excludeNonConclusiveProteinGroups;
		this.prideGenerationSoftware = prideGenerationSoftware;
	}

	/**
	 * 
	 * @param experiment
	 * @param controlVocabularyUtil
	 * @param addPeakList
	 * @param removeNotMatchedSpectra
	 *            if true, resulting PRIDE Experiment element will not contain
	 *            spectra that have not been matched
	 */
	public ExperimentCollectionAdapterFromExperiment(Experiment experiment,
			boolean gelbasedExperiment,
			ControlVocabularyManager controlVocabularyUtil,
			boolean addPeakList, boolean removeNotMatchedSpectra,
			boolean excludeNonConclusiveProteinGroups) {

		if (experiment == null) {
			throw new IllegalMiapeArgumentException(
					"Error creating PRIDE XML from null ExperimentList!");
		}
		this.factory = new ObjectFactory();
		this.cvManager = controlVocabularyUtil;
		this.experiment = experiment;
		this.addPeakList = addPeakList;
		this.removeNoMatchedSpectra = removeNotMatchedSpectra;
		this.gelBasedExperiment = gelbasedExperiment;
		this.excludeNonConclusiveProteinGroups = excludeNonConclusiveProteinGroups;
		this.prideGenerationSoftware = "ProteoRed MIAPE Extractor";
	}

	public ExperimentCollectionAdapterFromExperiment(Experiment experiment,
			boolean gelbasedExperiment,
			ControlVocabularyManager controlVocabularyUtil,
			boolean addPeakList, boolean removeNotMatchedSpectra,
			boolean excludeNonConclusiveProteinGroups,
			String prideGenerationSoftware) {

		if (experiment == null) {
			throw new IllegalMiapeArgumentException(
					"Error creating PRIDE XML from null ExperimentList!");
		}
		this.factory = new ObjectFactory();
		this.cvManager = controlVocabularyUtil;
		this.experiment = experiment;
		this.addPeakList = addPeakList;
		this.removeNoMatchedSpectra = removeNotMatchedSpectra;
		this.gelBasedExperiment = gelbasedExperiment;
		this.excludeNonConclusiveProteinGroups = excludeNonConclusiveProteinGroups;
		this.prideGenerationSoftware = prideGenerationSoftware;
	}

	public ExperimentCollectionAdapterFromExperiment(Experiment experiment,
			ControlVocabularyManager controlVocabularyUtil,
			boolean addPeakList, boolean removeNotMatchedSpectra,
			boolean excludeNonConclusiveProteinGroups,
			String prideGenerationSoftware) {

		if (experiment == null) {
			throw new IllegalMiapeArgumentException(
					"Error creating PRIDE XML from null ExperimentList!");
		}
		this.factory = new ObjectFactory();
		this.cvManager = controlVocabularyUtil;
		this.experiment = experiment;
		this.addPeakList = addPeakList;
		this.removeNoMatchedSpectra = removeNotMatchedSpectra;
		this.gelBasedExperiment = false;
		this.excludeNonConclusiveProteinGroups = excludeNonConclusiveProteinGroups;
		this.prideGenerationSoftware = prideGenerationSoftware;
	}

	public ExperimentCollectionAdapterFromExperiment(Experiment experiment,
			ControlVocabularyManager controlVocabularyUtil,
			boolean addPeakList, boolean removeNotMatchedSpectra,
			boolean excludeNonConclusiveProteinGroups) {

		this(experiment, false, controlVocabularyUtil, addPeakList,
				removeNotMatchedSpectra, excludeNonConclusiveProteinGroups);
	}

	@Override
	public ExperimentCollection adapt() {
		ExperimentCollection experimentCollection = factory
				.createExperimentCollection();
		experimentCollection
				.setVersion(PrideControlVocabularyXmlFactory.PRIDE_VERSION);
		if (this.experiment != null) {
			experimentCollection.getExperiment().add(
					new ExperimentAdapterFromExperiment(factory, cvManager,
							this.gelBasedExperiment, experiment, addPeakList,
							removeNoMatchedSpectra,
							excludeNonConclusiveProteinGroups,
							prideGenerationSoftware).adapt());

		}
		return experimentCollection;
	}
}
